์ž‘์„ฑ: 2026-03-04 04:03:38์ˆ˜์ •: 2026-03-04 04:03:38

Spring Boot ๋ณด์•ˆ ๊ธฐ์ดˆ (Spring Security)

์Šคํ”„๋ง ๋ถ€ํŠธ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์˜ ์ธ์ฆ(Authentication)๊ณผ ์ธ๊ฐ€(Authorization)๋ฅผ ๋‹ด๋‹นํ•˜๋Š” ํ•ต์‹ฌ ๋ณด์•ˆ ํ”„๋ ˆ์ž„์›Œํฌ์ธ Spring Security์˜ ๊ธฐ์ดˆ ์„ค์ •๊ณผ ํ™œ์šฉ๋ฒ•์„ ์ •๋ฆฌํ•ฉ๋‹ˆ๋‹ค. 2026๋…„ ๊ธฐ์ค€ ์ตœ์‹  ๋ณด์•ˆ ์„ค์ •์„ ๋ฐ˜์˜ํ•ฉ๋‹ˆ๋‹ค.


1. Spring Security ๊ฐœ์š”

Spring Security๋Š” "์ธ์ฆ(๋ˆ„๊ตฌ์ธ๊ฐ€?)"๊ณผ "์ธ๊ฐ€(์–ด๋–ค ๊ถŒํ•œ์ด ์žˆ๋Š”๊ฐ€?)"๋ฅผ ์ œ์–ดํ•˜๋Š” ๊ฐ•๋ ฅํ•œ ๋ณด์•ˆ ํ”„๋ ˆ์ž„์›Œํฌ์ž…๋‹ˆ๋‹ค. ํ•„ํ„ฐ ๊ธฐ๋ฐ˜์œผ๋กœ ์ž‘๋™ํ•˜๋ฉฐ, ์Šคํ”„๋ง ๋ถ€ํŠธ์™€ ๊ฒฐํ•ฉํ•˜์—ฌ ๋Œ€๋ถ€๋ถ„์˜ ์„ค์ •์„ ์ž๋™์œผ๋กœ ์ˆ˜ํ–‰ํ•ด ์ค๋‹ˆ๋‹ค.


2. ๊ธฐ๋ณธ ์„ค์ • (Dependencies)

Maven (pom.xml)

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-security</artifactId>
</dependency>

Gradle (build.gradle)

dependencies {
    implementation 'org.springframework.boot:spring-boot-starter-security'
}

3. ๋ณด์•ˆ ์„ค์ • ์ปค์Šคํ„ฐ๋งˆ์ด์ง• (SecurityConfig)

์ตœ์‹  ์Šคํ”„๋ง ์‹œํ๋ฆฌํ‹ฐ๋Š” WebSecurityConfigurerAdapter ์ƒ์† ๋ฐฉ์‹์ด ์•„๋‹Œ, SecurityFilterChain ๋นˆ์„ ๋“ฑ๋กํ•˜๋Š” ๋ฐฉ์‹์„ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค.

@Configuration
@EnableWebSecurity
public class SecurityConfig {
 
    @Bean
    public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
        http
            .csrf(csrf -> csrf.disable()) // REST API ํ™˜๊ฒฝ์—์„œ๋Š” CSRF ๋น„ํ™œ์„ฑํ™” ๊ถŒ์žฅ
            .authorizeHttpRequests(auth -> auth
                .requestMatchers("/api/public/**").permitAll() // ๋ˆ„๊ตฌ๋‚˜ ์ ‘๊ทผ ๊ฐ€๋Šฅ
                .requestMatchers("/api/admin/**").hasRole("ADMIN") // ๊ด€๋ฆฌ์ž๋งŒ ์ ‘๊ทผ ๊ฐ€๋Šฅ
                .anyRequest().authenticated() // ๋‚˜๋จธ์ง€๋Š” ๋กœ๊ทธ์ธ ํ•„์ˆ˜
            )
            .httpBasic(Customizer.withDefaults()); // ๊ธฐ๋ณธ ์ธ์ฆ ๋ฐฉ์‹ ์‚ฌ์šฉ
            
        return http.build();
    }
 
    @Bean
    public PasswordEncoder passwordEncoder() {
        return new BCryptPasswordEncoder(); // ๋น„๋ฐ€๋ฒˆํ˜ธ๋Š” ๋ฐ˜๋“œ์‹œ ์•”ํ˜ธํ™”ํ•˜์—ฌ ์ €์žฅ
    }
}

4. ์‚ฌ์šฉ์ž ์ธ์ฆ (InMemoryUser)

ํ…Œ์ŠคํŠธ ๋ชฉ์ ์œผ๋กœ ๋ฉ”๋ชจ๋ฆฌ์— ์‚ฌ์šฉ์ž๋ฅผ ๋“ฑ๋กํ•˜๋Š” ๋ฐฉ๋ฒ•์ž…๋‹ˆ๋‹ค. ์‹ค๋ฌด์—์„œ๋Š” DB ์—ฐ๋™(UserDetailsService)์„ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค.

@Bean
public UserDetailsService userDetailsService() {
    UserDetails user = User.builder()
            .username("user")
            .password(passwordEncoder().encode("1234"))
            .roles("USER")
            .build();
    return new InMemoryUserDetailsManager(user);
}

5. ํ•ต์‹ฌ ๋ณด์•ˆ ๊ฐœ๋…

  1. CSRF (Cross-Site Request Forgery): ์‚ฌ์ดํŠธ ๊ฐ„ ์š”์ฒญ ์œ„์กฐ ๋ฐฉ์ง€ ๊ธฐ๋Šฅ. REST API(State-less) ํ™˜๊ฒฝ์—์„œ๋Š” ์ฃผ๋กœ ๋„๊ณ  ํ† ํฐ(JWT ๋“ฑ) ๋ฐฉ์‹์„ ์”๋‹ˆ๋‹ค.
  2. CORS (Cross-Origin Resource Sharing): ๋‹ค๋ฅธ ๋„๋ฉ”์ธ(์˜ˆ: React ์•ฑ)์—์„œ ๋ฐฑ์—”๋“œ API๋ฅผ ํ˜ธ์ถœํ•  ์ˆ˜ ์žˆ๋„๋ก ํ—ˆ์šฉํ•˜๋Š” ์„ค์ •์ž…๋‹ˆ๋‹ค.
  3. AuthenticationManager: ์‹ค์ œ ์ธ์ฆ ๋กœ์ง์„ ์ด๊ด„ํ•˜๋Š” ํ•ต์‹ฌ ์ปดํฌ๋„ŒํŠธ์ž…๋‹ˆ๋‹ค.

6. ์š”์•ฝ

  • ์˜์กด์„ฑ ์ถ”๊ฐ€๋งŒ์œผ๋กœ ๊ธฐ๋ณธ์ ์ธ ๋ณด์•ˆ์ด ์‹œ์ž‘๋ฉ๋‹ˆ๋‹ค.
  • SecurityFilterChain์„ ํ†ตํ•ด ์„ธ๋ฐ€ํ•œ ์ ‘๊ทผ ๊ถŒํ•œ(์ธ๊ฐ€)์„ ์„ค์ •ํ•ฉ๋‹ˆ๋‹ค.
  • ๋น„๋ฐ€๋ฒˆํ˜ธ ์•”ํ˜ธํ™”๋Š” ์„ ํƒ์ด ์•„๋‹Œ ํ•„์ˆ˜์ž…๋‹ˆ๋‹ค (BCrypt).

๋ณด์•ˆ์€ ๊ธฐ๋Šฅ์„ ์™„์„ฑํ•œ ํ›„์— ๋ง๋ถ™์ด๋Š” ๊ฒƒ์ด ์•„๋‹ˆ๋ผ, ์„ค๊ณ„ ๋‹จ๊ณ„๋ถ€ํ„ฐ ๊ณ ๋ คํ•ด์•ผ ํ•˜๋Š” ํ•„์ˆ˜ ์š”์†Œ์ž…๋‹ˆ๋‹ค.